import { Request, Response } from 'express';
import { parse } from 'url';
import fs from 'fs';
import path from 'path';
import { ImagesListItem, ImagesListParams } from '@/pages/OnlineImage/data';

/**
 * 默认id为100的在线图库文件夹为根目录
 * 所有数据，包括新增文件夹均在根目录下进行操作
 */
const ImagesInfo: { title: string; src: string }[] = [];

const files = fs.readdirSync(path.resolve(__dirname, '../public/images'));
files.forEach((file) => {
  const ext = path.extname(file);
  const filename = path.basename(file, ext);
  ImagesInfo.push({ title: filename, src: `/images/${file}` });
});

/**
 * 获取文件夹数据
 */
const defaultList: ImagesListItem[] = [
  {
    title: '在线图库',
    name: '在线图库',
    id: '100',
    key: '100',
    icon: '',
    src: '',
    type: 'file',
    parentId: '',
    isLeaf: false,
    children: [],
  },
];

/**
 * 获取文件夹列表
 */
function getFile(req: Request, res: Response, u: string) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }
  // 默认分页数据
  const params = parse(realUrl, true).query as unknown as ImagesListParams;

  let dataSource: ImagesListItem[] = [...defaultList];

  // 根据文件夹id进行查询, 传空返回所有数据
  if (params.id) {
    dataSource = [...defaultList].filter((data) => data.id === params.id);
  }

  const result = {
    data: dataSource,
    success: true,
  };

  return res.json(result);
}

/**
 * 增加文件夹
 */
function postFile(req: Request, res: Response, u: string, b: Request) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }

  const body = (b && b.body) || req.body;
  const { method, title } = body;

  switch (method) {
    case 'add':
      (() => {
        const newFile: ImagesListItem = {
          id: ((defaultList.length + 1) * 100).toString(),
          key: ((defaultList.length + 1) * 100).toString(),
          title,
          name: title,
          type: 'file',
          parentId: '',
          icon: '',
          src: '',
          isLeaf: false, // 默认文件夹都不是叶子节点
          children: [],
        };
        defaultList.push(newFile);
        return res.json(newFile);
      })();
      return;
    default:
      break;
  }
  const result = {
    list: defaultList,
  };

  res.json(result);
}

/**
 * 初始化获取图片数据
 */
const genList = (current: number, pageSize: number) => {
  const imagesListDataSource: ImagesListItem[] = [];

  for (let i = 0; i < pageSize; i++) {
    const index = (current - 1) * 10 + i;
    // 取 0 - ImagesInfo.length-1 随机整数
    const randomImagesIndex = Math.floor(Math.random() * ImagesInfo.length);
    imagesListDataSource.push({
      id: index.toString(),
      key: index.toString(),
      title: ImagesInfo[randomImagesIndex].title,
      name: ImagesInfo[randomImagesIndex].title,
      src: ImagesInfo[randomImagesIndex].src,
      type: 'image',
      isLeaf: true,
      // 默认根目录文件夹id是100
      parentId: '100',
    });
  }
  imagesListDataSource.reverse();
  return imagesListDataSource;
};

let imagesListDataSource = genList(1, 50);

/**
 * 查询图片
 * 初始化查询与点击文件夹查询一致，必须要传文件夹id
 * 其中初始化查询时，默认传入第一个根目录id
 */
function getImages(req: Request, res: Response, u: string) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }
  // 默认分页数据
  const { currentPage = 1, pageSize = 10 } = req.query;
  const params = parse(realUrl, true).query as unknown as ImagesListParams;

  let dataSource: ImagesListItem[] = [...imagesListDataSource];

  // 根据文件夹id进行查询, 传空返回所有数据
  if (params.type === 'file') {
    if (params.id) {
      dataSource = [...imagesListDataSource].filter((data) => data.parentId === params.id);
    }
  }

  // 根据parentId进行查询，传空返回所有数据
  if (params.parentId) {
    dataSource = [...imagesListDataSource].filter((data) => data.parentId === params.parentId);
  }

  // 根据图片名称进行查询
  if (params.title) {
    dataSource = [...imagesListDataSource].filter(
      (data) => data.title.indexOf(params.title as string) > -1,
    );
  }

  let current = currentPage > 0 ? currentPage : 1;
  let _dataSource = dataSource.slice(
    ((current as number) - 1) * (pageSize as number),
    (current as number) * (pageSize as number),
  );

  const result = {
    data: _dataSource,
    total: dataSource.length,
    success: true,
    pageSize,
    current: parseInt(`${params.currentPage}`, 10) || 1,
  };

  return res.json(result);
}

function postImages(req: Request, res: Response, u: string, b: Request) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }

  const body = (b && b.body) || req.body;
  const { method, id, title, parentId = '100' } = body;

  switch (method) {
    // 上传图片信息
    case 'add':
      (() => {
        // 去除文件名后缀
        const filename = path.basename(title, path.extname(title));
        const newRights: ImagesListItem = {
          id: (imagesListDataSource.length + 1).toString(),
          key: (imagesListDataSource.length + 1).toString(),
          title: filename,
          name: filename,
          type: 'image',
          parentId, // 默认上传到根目录文件下
          src: `/images/${title}`,
          isLeaf: true,
        };
        imagesListDataSource.unshift(newRights);
        return res.json(newRights);
      })();
      return;
    // 重命名或移动图片
    case 'update':
      (() => {
        let newRights = {};
        imagesListDataSource = imagesListDataSource.map((item) => {
          if (item.id === id) {
            newRights = { ...item, title };
            return { ...item, title };
          }
          return item;
        });
        return res.json(newRights);
      })();
      return;
    // 删除文件
    case 'delete':
      imagesListDataSource = imagesListDataSource.filter((item) => id !== item.id);
      break;
    default:
      break;
  }

  const result = {
    list: imagesListDataSource,
    pagination: {
      total: imagesListDataSource.length,
    },
  };

  res.json(result);
}

/**
 * 上传图片
 */
function uploadFile(params: any, res: Response) {
  let success = false;
  const _path = path.resolve(__dirname, '../public/images', params?.files[0].originalname);

  new Promise((resolve, reject) => {
    fs.writeFile(_path, params?.files[0].buffer, (err) => {
      if (err) {
        console.log(err);
        reject(err);
      } else {
        success = true;
        resolve(success);
      }
    });
  }).finally(() => {
    const result = {
      success,
    };
    res.json(result);
  });
}

export default {
  'GET /api/images': getImages,
  'POST /api/images': postImages,
  'GET /api/file': getFile,
  'POST /api/file': postFile,
  'POST /api/upload': uploadFile,
};
